package org.zoomdev.zoom.dao.impl;

import org.zoomdev.zoom.dao.Entity;
import org.zoomdev.zoom.dao.EntityField;
import org.zoomdev.zoom.dao.Sql;
import org.zoomdev.zoom.dao.SqlDriver;
import org.zoomdev.zoom.dao.structs.TableMeta;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class RecordEntity extends Entity<Map<String, Object>> {
    public static final char COMMA = ',';  //comma
    public static final char QM = '?';  //Question Mark

    public RecordEntity(SqlDriver sqlDriver, TableMeta table, EntityField[] primaryKeys, EntityField[] entityFields) {
        super(sqlDriver, table, primaryKeys, entityFields);
    }


    @Override
    public void buildSelect(SimpleSelect select, SqlConfig config) {
        if (select.limit > 0) {
            driver.buildLimit(this, select, config);
        } else {
            select.buildSelect(config.sql);
            config.values.addAll(select.values);
        }
    }

    @Override
    public void buildDelete(SimpleSelect select, SqlConfig config) {
        select.buildDelete(config.sql);
        config.values.addAll(select.values);
    }

    @Override
    public void buildInsert(Map<String, Object> record, SimpleSelect select, SqlConfig config) {
        record.putAll(config.placeholder);

        StringBuilder sql = config.sql;
        List<Object> values = config.values;
        sql.append("INSERT INTO ").append(table).append(" (");
        boolean first = true;
        for (Map.Entry<String, Object> entry : record.entrySet()) {
            Object value = entry.getValue();
            if (first) {
                first = false;
            } else {
                sql.append(COMMA);
            }
            sql.append(entry.getKey());
            if (value instanceof Sql.PlaceHolder) {
                Sql.PlaceHolder placeHolder = (Sql.PlaceHolder) value;
                Collections.addAll(values, placeHolder.args);
            } else {
                values.add(value);
            }
        }
        sql.append(") VALUES (");
        first = true;
        for (Map.Entry<String, Object> entry : record.entrySet()) {
            Object value = entry.getValue();
            if (first) {
                first = false;
            } else {
                sql.append(COMMA);
            }
            if (value instanceof Sql.PlaceHolder) {
                Sql.PlaceHolder placeHolder = (Sql.PlaceHolder) value;
                sql.append(placeHolder.value);
            } else {
                sql.append(QM);
            }
        }
        sql.append(")");
    }

    @Override
    public void buildUpdate(Map<String, Object> record, SimpleSelect select, SqlConfig config) {
        record.putAll(config.placeholder);

        StringBuilder sql = config.sql;
        List<Object> values = config.values;

        sql.append("UPDATE ").append(table);
        boolean first = true;
        for (Map.Entry<String, Object> entry : record.entrySet()) {
            Object value = entry.getValue();
            if (config.ignoreNull && value == null) {
                continue;
            }
            if (first) {
                first = false;
                sql.append(" SET ");
            } else {
                sql.append(COMMA);
            }
            sql.append(entry.getKey());
            if (value instanceof Sql.PlaceHolder) {
                Sql.PlaceHolder placeHolder = (Sql.PlaceHolder) value;
                Collections.addAll(values, placeHolder.args);
                sql.append("=").append(placeHolder.value);
            } else {
                values.add(value);
                sql.append("=?");
            }
        }

        select.buildWhere(sql);
        values.addAll(select.values);
    }

    @Override
    public Object fromResultSet(ResultSet rs) throws SQLException {
        return null;
    }
}
